package pers.bc.utils.yonyou;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import nc.jdbc.framework.processor.ColumnProcessor;
import nc.jdbc.framework.processor.MapListProcessor;
import nc.jdbc.framework.processor.MapProcessor;
import nc.vo.org.OrgVO;
import nc.vo.pub.BusinessException;
import nc.vo.pub.lang.UFBoolean;
import pers.bc.utils.pub.CollectionUtil;
import pers.bc.utils.pub.PubEnvUtil;
import pers.bc.utils.pub.StringUtil;
import pers.bc.utils.sql.SqlHelper;

/**
 * PubApp 工具类
 * @qualiFild PubAppUtilProcess.java<br>
 * @author：LiBencheng<br>
 * @date Created on 2017-2-23<br>
 * @version 1.0<br>
 */
public class PubAppUtilProcess
{
    static Integer TWO_LENGTH = 8;
    static Integer THREE_LENGTH = 12;
    
    static java.lang.String ORGNAME = "orgname";
    static java.lang.String NEWSTR = "new";
    static java.lang.String OLDSTR = "old";
     
    public static  Map< String,Object >  getTimeStamp(String tableName, String pKFieldName, String condition) throws BusinessException
    {
        return new PubAppUtilProcess().getTimeStamp(  tableName,  pKFieldName ,  condition, null);
    }
    
    /**
     * *********************************************************** <br>
     * *说明：获取对应表的时间戳，返回 map<主键，时间戳><br>
     * @see <br>
     * @param tableName 表名
     * @param pKFieldName 主键名称
     * @param condition 条件SQL，不传where 关键字
     * @param orderStr 排序SQL,不传order by 关键字
     * @return ap<主键，时间戳>
     * @throws BusinessException <br> 
     * @author LiBencheng <br>
     * @date Created on 2021-3-29 <br>
     * @time 17:23:27 <br>
     * @version 1.0 <br>
     ************************************************************* <br>
     */
    @SuppressWarnings("unchecked")
    private  Map< String,Object >  getTimeStamp(String tableName, String pKFieldName, String condition, String orderStr) throws BusinessException
    {
       String sql = SqlHelper.getSelectSQL(tableName, new String[]{"'"+tableName+"' AS table ",pKFieldName,"ts"},condition, orderStr);
       
       List< Map< String,Object > > dataList =   
               (List<Map<String, Object>>) YonYouUtilbc.getBaseDAOQueryBSyC().executeQuery(sql , new MapListProcessor());
        
      return  CollectionUtil.receiveGroupMap(dataList, pKFieldName);
      
    }
    
    /**
     * 获取单位的名称
     * @param pk_org 单位主键
     * @param inrCodeLength 单位的长度
     * @return
     * @throws BusinessException
     * @author libchc
     */
    public static String getOrgName(String pk_org, Integer inrCodeLength) throws BusinessException
    {
        String sql = "SELECT name FROM org_orgs WHERE pk_org='" + getHigherOrgPK(pk_org, inrCodeLength) + "'";
        // Object name = YonYouUtilbc.getBaseDAOQueryBSyC().executeQuery(sql, new ColumnProcessor());
        // return PubEnvUtil.isEmptyObj(name) ? null : name.toString();
        
        return StringUtil.valueOfEmpty(YonYouUtilbc.getBaseDAOQueryBSyC().executeQuery(sql, new ColumnProcessor()));
        
    }
    
    /**
     * 获取单位的编码
     * @param pk_org 单位主键
     * @param inrCodeLength 单位的长度
     * @return
     * @throws BusinessException
     * @author libchc
     */
    public static String getOrgCode(String pk_org, Integer inrCodeLength) throws BusinessException
    {
        String sql = "SELECT code FROM org_orgs WHERE pk_org='" + getHigherOrgPK(pk_org, inrCodeLength) + "'";
        // Object code = YonYouUtilbc.getBaseDAOQueryBSyC().executeQuery(sql, new ColumnProcessor());
        // return PubEnvUtil.isEmptyObj(code) ? null : code.toString();
        
        return StringUtil.valueOfEmpty(YonYouUtilbc.getBaseDAOQueryBSyC().executeQuery(sql, new ColumnProcessor()));
        
    }
    
    /**
     * 是二级、三级组织
     * @param pk_org
     * @return String[]
     * @throws BusinessException
     */
    public static String[] getHigherOrgPK(final String pk_org) throws BusinessException
    {
        // ArrayList<String> pks = new ArrayList<String>();
        // pks.add(getHigherOrgPK(pk_org, TWO_LENGTH));
        // pks.add(getHigherOrgPK(pk_org, THREE_LENGTH));
        // return pks.toArray(new String[0]);
        
        return new ArrayList<String>()
        {
            /** @date 2021-3-18 */
            private static final long serialVersionUID = 286443010741069836L;
            
            {
                add(getHigherOrgPK(pk_org, TWO_LENGTH));
                add(getHigherOrgPK(pk_org, THREE_LENGTH));
            }
            
        }.toArray(new String[0]);
        
    }
    
    /**
     * *********************************************************** <br>
     * 说明：获取组织指定上级pk_org <br>
     * @see <br>
     * @param pk_org 组织pk
     * @param inrCodeLength innercodr长度
     * @return 指定的上级组织 可以是二级、三级、四级等
     * @throws BusinessException <br>
     * @String <br>
     * @methods nc.pub.tools.HROrgProcessorUtils#getHigherOrgPK <br>
     * @author licheng <br>
     * @date Created on 2020-4-7 <br>
     * @time 上午9:43:20 <br>
     * @version 1.0 <br>
     ************************************************************* <br>
     */
    public static String getHigherOrgPK(String pk_org, Integer inrCodeLength) throws BusinessException
    {
        if (PubEnvUtil.equals(is2PowerAnother(inrCodeLength), -1)) return pk_org;
        return getFatherorgPK(pk_org, inrCodeLength, Boolean.TRUE);
    }
    
    /**
     * *********************************************************** <br>
     * *说明：获取部门指定上级pk_dept <br>
     * @see <br>
     * @param pk_dept 部门pk
     * @param inrCodeLength innercodr长度
     * @return 指定的上级组织 可以是二级、三级、四级等
     * @throws BusinessException <br>
     * @String <br>
     * @methods nc.pub.tools.bc.HRPubUtils#getHigherDeptPK <br>
     * @author LiBencheng <br>
     * @date Created on 2021-3-29 <br>
     * @time 16:44:08 <br>
     * @version 1.0 <br>
     ************************************************************* <br>
     */
    public static String getHigherDeptPK(String pk_dept, Integer inrCodeLength) throws BusinessException
    {
        if (PubEnvUtil.equals(is2PowerAnother(inrCodeLength), -1)) return pk_dept;
        return getFatherorgPK(pk_dept, inrCodeLength, Boolean.FALSE);
    }
    
    /**
     * *********************************************************** <br>
     * *说明：获取所有部门或组织相关下级<br>
     * @see <br>
     * @param pk_org
     * @param isOrg
     * @return
     * @throws BusinessException <br>
     * @List<?> <br>
     * @methods nc.pub.tools.bc.HRPubUtils#getLowerLevel <br>
     * @author LiBencheng <br>
     * @date Created on 2021-3-29 <br>
     * @time 17:23:27 <br>
     * @version 1.0 <br>
     ************************************************************* <br>
     */
    public static List<?> getLowerLevel(String pk_org, Boolean isOrg) throws BusinessException
    {
        return getRelevantOrgSQL(pk_org, isOrg, Boolean.FALSE);
    }
    
    /**
     * *********************************************************** <br>
     * *说明： 获取所有下级组织<br>
     * @see <br>
     * @param pk_org
     * @return
     * @throws BusinessException <br>
     * @List<?> <br>
     * @methods nc.pub.tools.bc.HRPubUtils#getOrgLowerLevel <br>
     * @author LiBencheng <br>
     * @date Created on 2021-3-29 <br>
     * @time 17:26:24 <br>
     * @version 1.0 <br>
     ************************************************************* <br>
     */
    public static List<?> getOrgLowerLevel(String pk_org) throws BusinessException
    {
        return getLowerLevel(pk_org, Boolean.TRUE);
    }
    
    /**
     * *********************************************************** <br>
     * *说明：获取所有下级部门 <br>
     * @see <br>
     * @param pk_dept
     * @return
     * @throws BusinessException <br>
     * @List<?> <br>
     * @methods nc.pub.tools.bc.HRPubUtils#getDeptLowerLevel <br>
     * @author LiBencheng <br>
     * @date Created on 2021-3-29 <br>
     * @time 17:26:40 <br>
     * @version 1.0 <br>
     ************************************************************* <br>
     */
    public static List<?> getDeptLowerLevel(String pk_dept) throws BusinessException
    {
        return getLowerLevel(pk_dept, Boolean.FALSE);
    }
    
    /**
     * *********************************************************** <br>
     * *说明：获取所有组织或部门的上级 <br>
     * @see <br>
     * @param pk_org
     * @param isOrg
     * @return
     * @throws BusinessException <br>
     * @List<?> <br>
     * @methods nc.pub.tools.bc.HRPubUtils#getOrgFatherorg <br>
     * @author LiBencheng <br>
     * @date Created on 2021-3-29 <br>
     * @time 17:33:20 <br>
     * @version 1.0 <br>
     ************************************************************* <br>
     */
    public static List<?> getOrgFatherorg(String pk_org, Boolean isOrg) throws BusinessException
    {
        return getRelevantOrgSQL(pk_org, isOrg, Boolean.TRUE);
    }
    
    /**
     * *********************************************************** <br>
     * *说明：：获取所有组织的上级 <br>
     * @see <br>
     * @param pk_org
     * @return
     * @throws BusinessException <br>
     * @List<?> <br>
     * @methods nc.pub.tools.bc.HRPubUtils#getOrgFatherorg <br>
     * @author LiBencheng <br>
     * @date Created on 2021-3-29 <br>
     * @time 17:34:09 <br>
     * @version 1.0 <br>
     ************************************************************* <br>
     */
    public static List<?> getOrgFatherorg(String pk_org) throws BusinessException
    {
        return getRelevantOrgSQL(pk_org, Boolean.TRUE, Boolean.TRUE);
    }
    
    /**
     * *********************************************************** <br>
     * *说明： ：获取所有部门的上级 <br>
     * @see <br>
     * @param pk_org
     * @return
     * @throws BusinessException <br>
     * @List<?> <br>
     * @methods nc.pub.tools.bc.HRPubUtils#getDeptFatherorg <br>
     * @author LiBencheng <br>
     * @date Created on 2021-3-29 <br>
     * @time 17:34:19 <br>
     * @version 1.0 <br>
     ************************************************************* <br>
     */
    public static List<?> getDeptFatherorg(String pk_org) throws BusinessException
    {
        return getRelevantOrgSQL(pk_org, Boolean.FALSE, Boolean.TRUE);
    }
    
    private static String getFatherorgPK(String pk_org, Integer inrCodeLength, Boolean isOrg) throws BusinessException
    {
        String pk_fatherorg = pk_org;
        List<?> list = getRelevantOrgSQL(pk_org, isOrg, Boolean.TRUE);
        for (int i = 0, i$ = PubEnvUtil.getSize(list); i < i$; i++)
        {
            Map<?, ?> map = (Map<?, ?>) list.get(i);
            
            if (PubEnvUtil.equals(inrCodeLength, String.valueOf(map.get(OrgVO.INNERCODE)).length()))
            {
                pk_fatherorg = String.valueOf(map.get(OrgVO.PK_ORG));
                // 待本级的单独处理，返回其帽子虚拟公司
                if (String.valueOf(map.get(OrgVO.NAME)).contains("本级")) pk_fatherorg = String.valueOf(map.get(OrgVO.PK_FATHERORG));
            }
        }
        
        return pk_fatherorg;
    }
    
    /**
     * *********************************************************** <br>
     * *说明：获取 单位（组织或部门）的相关信息<br>
     * @see <br>
     * @param pk_org 单位（组织或部门）PK
     * @param isOrg 是否组织
     * @param isFatherorg 是否上级
     * @return
     * @throws BusinessException <br>
     * @List<?> <br>
     * @methods nc.pub.tools.bc.HRPubUtils#getRelevantOrgSQL <br>
     * @author LiBencheng <br>
     * @date Created on 2021-3-29 <br>
     * @time 17:34:34 <br>
     * @version 1.0 <br>
     ************************************************************* <br>
     */
    private static List<?> getRelevantOrgSQL(String pk_org, Boolean isOrg, Boolean isFatherorg) throws BusinessException
    {
        StringBuffer sql = new StringBuffer();
        if (isOrg)
        {
            sql.append(" SELECT");
            sql.append("    org_orgs.name           AS name,");
            sql.append("    org_orgs.code           AS code,");
            sql.append("    innercode               AS innercode,");
            sql.append("    org_orgs.pk_org         AS pk_org,");
            sql.append("    org_orgs.pk_fatherorg   AS pk_fatherorg");
            sql.append(" FROM");
            sql.append("    org_orgs org_orgs");
            sql.append(" START WITH pk_org = '");
            sql.append(pk_org);
            sql.append("'");
            sql.append("    AND isbusinessunit = 'Y'  CONNECT BY PRIOR  ");
            
            if (isFatherorg)
            {
                sql.append(" pk_fatherorg = pk_org");
                sql.append(" ORDER BY innercode ASC");
            }
            else
            {
                sql.append(" pk_org =pk_deptpk_fatherorg ");
                sql.append(" ORDER BY innercode ASC");
            }
        }
        else
        {
            sql.append("SELECT dept. *,org.name AS orgname,");
            sql.append(" org.code AS orgcode FROM ( ");
            sql.append(" SELECT");
            sql.append("     org_dept.name           AS name,");
            sql.append("     org_dept.code           AS code,");
            sql.append("     org_dept.depttype       AS depttype,");
            sql.append("     org_dept.innercode      AS innercode,");
            sql.append("     org_dept.pk_dept        AS pk_dept,");
            sql.append("     org_dept.pk_org         AS pk_org,");
            sql.append("     org_dept.pk_fatherorg   AS pk_fatherorg");
            sql.append(" FROM org_dept org_dept");
            sql.append(" START WITH");
            sql.append("     org_dept.pk_dept = '");
            sql.append(pk_org);
            sql.append("' CONNECT BY PRIOR ");
            if (isFatherorg)
            {
                sql.append(" pk_fatherorg = pk_dept");
                sql.append(" ORDER BY innercode ASC )dept LEFT JOIN org_orgs org ON dept.pk_org = org.pk_org");
                
            }
            else
            {
                sql.append(" PRIOR =pk_deptpk_fatherorg ");
                sql.append(" ORDER BY innercode ASC )dept LEFT JOIN org_orgs org ON dept.pk_org = org.pk_org");
            }
            
        }
        
        return (List<?>) YonYouUtilbc.getBaseDAOQueryBSyC().executeQuery(sql.toString(), new MapListProcessor());
        
    }
    
    /**
     * *********************************************************** <br>
     * *说明：递归获取上级单位 ,性能不高<br>
     * @see <br>
     * @param pk_org
     * @param inrCodeLength
     * @param isOrg
     * @return
     * @throws BusinessException <br>
     * @String <br>
     * @methods nc.pub.tools.bc.HRPubUtils#getFatherorgRecursionPK <br>
     * @author LiBencheng <br>
     * @date Created on 2021-3-29 <br>
     * @time 16:59:11 <br>
     * @version 1.0 <br>
     ************************************************************* <br>
     */
    public static String getFatherorgRecursionPK(String pk_org, Integer inrCodeLength, Boolean isOrg) throws BusinessException
    {
        String pk_fatherorg = pk_org;
        StringBuffer sql = new StringBuffer();
        if (isOrg)
        {
            sql.append(" SELECT org_orgs.name AS name,org_orgs.code AS code,innercode AS innercode,");
            sql.append(" org_orgs.pk_org AS pk_org,org_orgs.pk_fatherorg AS pk_fatherorg");
            sql.append(" FROM org_orgs org_orgs WHERE isbusinessunit ='Y' AND org_orgs.pk_org=('").append(pk_org).append("')");
        }
        else
        {
            sql.append(" SELECT org_dept.name AS name,org_dept.code AS code,org_dept.innercode AS innercode,");
            sql.append(" org_dept.pk_dept AS pk_dept,org_dept.pk_dept AS pk_org,org_dept.pk_fatherorg AS pk_fatherorg ");
            sql.append(" FROM org_dept org_dept WHERE org_dept.pk_dept = '").append(pk_org).append("'");
            
        }
        Map<?, ?> map = (Map<?, ?>) YonYouUtilbc.getBaseDAOQueryBSyC().executeQuery(sql.toString(), new MapProcessor());
        // 集团单独处理
        if (PubEnvUtil.equals(4, String.valueOf(map.get(OrgVO.INNERCODE)).length())) return pk_fatherorg;
        if (PubEnvUtil.equals(inrCodeLength, String.valueOf(map.get(OrgVO.INNERCODE)).length()))
        {
            pk_fatherorg = String.valueOf(map.get(OrgVO.PK_ORG));
            // 待本级的单独处理，返回其帽子虚拟公司
            if (String.valueOf(map.get(OrgVO.NAME)).contains("本级")) pk_fatherorg = String.valueOf(map.get(OrgVO.PK_FATHERORG));
        }
        else
        {
            // 二级单位本级, 返回的三级单位是本级本身
            if (PubEnvUtil.equals(TWO_LENGTH, String.valueOf(map.get(OrgVO.INNERCODE)).length())//
                && PubEnvUtil.equals(THREE_LENGTH, String.valueOf(map.get(OrgVO.INNERCODE)).length())) pk_fatherorg =
                String.valueOf(map.get(OrgVO.PK_ORG));
            else
                pk_fatherorg = getFatherorgPK(String.valueOf(map.get(OrgVO.PK_FATHERORG)), inrCodeLength, isOrg);
        }
        
        return pk_fatherorg;
    }
    
    /**
     * *********************************************************** <br>
     * *说明： 移位判断是不是2的NCF<br>
     * @see <br>
     * @param num
     * @return <br>
     * @int <br>
     * @methods nc.pub.tools.bc.HRPubUtils#binaryIs2Power <br>
     * @author LiBencheng <br>
     * @date Created on 2021-3-26 <br>
     * @time 11:31:16 <br>
     * @version 1.0 <br>
     ************************************************************* <br>
     */
    public static int is2PowerBinary(int inrCodeLength)
    {
        if (inrCodeLength < 2) return -1;
        int temp = 1;
        while (inrCodeLength > temp)
        {
            temp <<= 1;
        }
        
        return temp == inrCodeLength ? 1 : -1;
    }
    
    /**
     * *********************************************************** <br>
     * *说明： 位与判断，最快<br>
     * @see <br>
     * @param num
     * @return <br>
     * @int <br>
     * @methods nc.pub.tools.bc.HRPubUtils#anotherIs2Power <br>
     * @author LiBencheng <br>
     * @date Created on 2021-3-26 <br>
     * @time 11:35:10 <br>
     * @version 1.0 <br>
     ************************************************************* <br>
     */
    public static int is2PowerAnother(int num)
    {
        if (num < 2) return -1;
        
        if ((num & num - 1) == 0) return 1;
        else
            return -1;
    }
    
    /**
     * *********************************************************** <br>
     * *说明： 递归算法实现<br>
     * @see <br>
     * @param num
     * @return <br>
     * @int <br>
     * @methods nc.pub.tools.bc.HRPubUtils#is2Power <br>
     * @author LiBencheng <br>
     * @date Created on 2021-3-26 <br>
     * @time 11:36:22 <br>
     * @version 1.0 <br>
     ************************************************************* <br>
     */
    public static int is2Power(int num)
    {
        if (num < 2) return -1;
        
        if (num == 2) return 1;
        else if (num % 2 == 0) return is2Power(num / 2);
        else
            return -1;
    }
    
    /**
     * *********************************************************** <br>
     * *说明： <br>
     * @see <br>
     * @param obj
     * @return <br>
     * @Boolean <br>
     * @methods nc.pub.tools.bc.HRPubUtils#isValue <br>
     * @author LiBencheng <br>
     * @date Created on 2021-3-16 <br>
     * @time 16:22:06 <br>
     * @version 1.0 <br>
     ************************************************************* <br>
     */
    public static Boolean isValue(Object obj)
    {
        return PubEnvUtil.isEmptyObj(obj) ? Boolean.FALSE : ((UFBoolean) obj).booleanValue();
    }
    
    /**
     * *********************************************************** <br>
     * *说明： 获取属性字段<br>
     * @see <br>
     * @param attrKey
     * @param isPsnjob
     * @param isOld
     * @return <br>
     * @java.lang.String <br>
     * @methods nc.bc.hr.pub.HRPubUtils#getAttrKey <br>
     * @author LiBencheng <br>
     * @date Created on 2021-2-26 <br>
     * @time 15:43:50 <br>
     * @version 1.0 <br>
     ************************************************************* <br>
     */
    public static java.lang.String getAttrKey(java.lang.String attrKey, Boolean isPsnjob, Boolean isOld)
    {
        return isPsnjob ? attrKey : (isOld ? (OLDSTR + attrKey) : (NEWSTR + attrKey));
    }
    
}
